﻿// --------------------------------
// <copyright file="MemberViewer.cs" company="Pattern Web Solutions">
//     Copyright © Simon Gill 2010. Distributed under the GPL.
// </copyright>
// <author>Simon Gill</author>
// ---------------------------------
// This file is part of League Manager

// League Manager is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.

// League Manager is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with League Manager.  If not, see <http://www.gnu.org/licenses/>.

namespace LeagueManager
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using LeagueManager.Models;

    public partial class MemberViewer : Form
    {
        private DateTime DefaultBirthdate = DateTime.Parse("1990-01-01");
        private DateTime CurrentBirthdate;

        private IMembershipRepository membership;
        
        private bool isDirty;

        private Member currentMember;

        public MemberViewer(IMembershipRepository repository)
        {
            this.InitializeComponent();

            CurrentBirthdate = DefaultBirthdate;

            this.membership = repository;

            this.LoadMembers();
            this.LoadGames();

            // If there is a member in the list, select it. Otherwise, select the New Member option.
            if (this.lstMembers.Items.Count > 1)
            {
                this.lstMembers.SelectedIndex = 1;
            }
            else
            {
                this.lstMembers.SelectedIndex = 0;
            }
        }

        private void LoadMembers()
        {
            Member[] members = this.membership.AllMembers().ToArray();

            this.lstMembers.Items.Clear();

            this.lstMembers.Items.Add("New Member...");

            this.lstMembers.Items.AddRange(members);
        }

        private void LoadGames()
        {
            Game[] games = this.membership.AllActiveGames().ToArray();
            this.lstGames.Items.Clear();
            this.lstGames.Items.AddRange(games);
        }

        private void Members_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.isDirty)
            {
                this.SaveAndReloadMembers(this, new EventArgs());
            }

            if (this.lstMembers.SelectedIndex < 0 && this.lstMembers.Items.Count > 1)
            {
                this.lstMembers.SelectedIndex = 1;
            }

            this.currentMember = this.lstMembers.SelectedItem as Member;
            if (this.currentMember == null)
            {
                this.currentMember = new Member();
            }

            this.GetControlValuesFromMember(this.currentMember);
        }

        private void SaveAndReloadMembers(object sender, EventArgs e)
        {
            this.SetMemberFromControlValues();

            this.membership.SaveMember(this.currentMember);

            this.isDirty = false;

            int selectedIndex = this.lstMembers.SelectedIndex;
            this.LoadMembers();
            this.lstMembers.SelectedIndex = selectedIndex;
        }

        private void GetControlValuesFromMember(Member member)
        {
            if (member != null)
            {
                this.txtName.Text = member.Name;
                this.txtAddress.Text = member.Address;
                this.txtEmail.Text = member.Email;
                this.txtPhone.Text = member.Phone;
                this.txtAltPhone.Text = member.AltPhone;

                if (member.DateOfBirth != DateTime.MinValue)
                {
                    CurrentBirthdate = member.DateOfBirth;
                }
                else
                {
                    CurrentBirthdate = DefaultBirthdate;
                }

                this.numYear.Value = CurrentBirthdate.Year;
                this.numMonth.Value = CurrentBirthdate.Month;
                this.numDay.Value = CurrentBirthdate.Day;

                var games = from mfg in member.MemberFavouriteGames select mfg.Game;

                for (int i = 0; i < this.lstGames.Items.Count; i++)
                {
                    this.lstGames.SetItemChecked(i, games.Contains(this.lstGames.Items[i] as Game));
                }

                // Fill Results controls
                this.lblWinAmount.Text = member.WinCount.ToString();
                this.lblLossAmount.Text = member.LossCount.ToString();

                if (member.WinCount != 0 || member.LossCount != 0)
                {
                    this.lblWinPercentageAmount.Text = (member.WinCount / (double)(member.WinCount + member.LossCount)).ToString("P2");
                }
                else
                {
                    this.lblWinPercentageAmount.Text = "-";
                }

                this.gvMatches.DataSource = (from g in member.Wins.Union(member.Losses) orderby g.ReportedDate select new { Game = g.Game.Name, Winner = g.WinningMember.Name, Loser = g.LosingMember.Name, Date = g.ReportedDate }).ToList();
                for (int i = 0; i < this.gvMatches.ColumnCount; i++)
                {
                    this.gvMatches.AutoResizeColumn(i, DataGridViewAutoSizeColumnMode.AllCells);
                }

                this.gvGames.DataSource = this.membership.GameResultsForMember(member);

                for (int i = 0; i < this.gvGames.ColumnCount; i++)
                {
                    this.gvGames.AutoResizeColumn(i, DataGridViewAutoSizeColumnMode.AllCells);
                }
            }
        }

        private void SetMemberFromControlValues()
        {
            this.currentMember.Name = this.txtName.Text;
            this.currentMember.Address = this.txtAddress.Text;
            this.currentMember.Email = this.txtEmail.Text;
            this.currentMember.Phone = this.txtPhone.Text;
            this.currentMember.AltPhone = this.txtAltPhone.Text;
            this.currentMember.DateOfBirth = this.CurrentBirthdate;

            this.membership.SetFavoriteGamesFor(this.currentMember, (from Game g in this.lstGames.CheckedItems select g));
        }

        private void MarkRecordDirty(object sender, EventArgs e)
        {
            this.isDirty = true;
        }

        private void Games_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            this.MarkRecordDirty(sender, e);
        }

        private void Issue_Click(object sender, EventArgs e)
        {
            try
            {
                this.membership.IssueMembershipNumber(this.currentMember, this.txtNewID.Text);
                this.SaveAndReloadMembers(sender, e);
            }
            catch (InvalidOperationException ex)
            {
                this.txtNewID.ForeColor = Color.Red;
                System.Diagnostics.Trace.WriteLine(ex.Message);
            }
        }

        private void Add_Click(object sender, EventArgs e)
        {
            this.lstMembers.SelectedIndex = 0;
            this.currentMember = new Member();
            this.currentMember.DateOfBirth = DefaultBirthdate;
            this.GetControlValuesFromMember(this.currentMember);
            this.MarkRecordDirty(sender, e);
            this.txtName.Focus();
        }

        private void NewID_TextChanged(object sender, EventArgs e)
        {
            this.txtNewID.ForeColor = Color.Black;
        }

        private void numYear_ValueChanged(object sender, EventArgs e)
        {
            CurrentBirthdate = CurrentBirthdate.AddYears((int)numYear.Value - CurrentBirthdate.Year);
            SetMaxDay(numDay, CurrentBirthdate);
        }

        private void numMonth_ValueChanged(object sender, EventArgs e)
        {
            CurrentBirthdate = CurrentBirthdate.AddMonths((int)numMonth.Value - CurrentBirthdate.Month);
            SetMaxDay(numDay, CurrentBirthdate);
        }

        private void SetMaxDay(NumericUpDown numDay,DateTime CurrentBirthdate)
        {
            // Go to next month then subtract the number of past the month, this gets you 
            numDay.Maximum = CurrentBirthdate.AddMonths(1).AddDays(-CurrentBirthdate.Day).Day;
        }

        private void numDay_ValueChanged(object sender, EventArgs e)
        {
            CurrentBirthdate = CurrentBirthdate.AddDays((int)numDay.Value - CurrentBirthdate.Day);
        }

        private void EnterNumericUpDownControl(object sender, EventArgs e)
        {
            ((NumericUpDown)sender).Select(0, ((NumericUpDown)sender).Value.ToString().Length);
        }


    }
}